﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;



namespace Treedata
{

    public class treeException : Exception
    {
        public
            treeException(string str)
            : base(str) { }
    };

    public class Nodelist
    {
        public
            int size()
        {
            return m_nodelist.Count;
        }

        public TreeDataNode this[int i]
        {
            get
            {
                return m_nodelist[i];
            }
            set
            {
                m_nodelist[i] = value;
            }
        }

        public List<TreeDataNode> m_nodelist = new List<TreeDataNode>();

    };

    public class TreeDataNode
    {
        public TreeDataNode() { }

        public Nodelist m_cdls;

        public TreeDataNode m_parent;

        public TreeDataNode parent
        {
            get
            {
                return m_parent;
            }
        }

        public Nodelist getchildren()
        {
            if (m_cdls == null)
                m_cdls = new Nodelist();
            return m_cdls;
        }

    };

    public class Tree
    {
        public Tree() { }

        public TreeDataNode root { get; set; } 

        public void insertnode(TreeDataNode node, TreeDataNode parent, TreeDataNode where)
        {
            if (parent == null)
            {
                if (root != null)
                    throw new treeException("root seted.");
                root = node;
            }
            else
            {
                parent.getchildren();
                if (where != null)
                {
                    int it = parent.m_cdls.m_nodelist.FindIndex(
                        delegate(TreeDataNode nd)
                        {
                            return nd == where;
                        });
                    parent.m_cdls.m_nodelist.Insert(it, node);
                }
                else
                    parent.m_cdls.m_nodelist.Add(node);

                node.m_parent = parent;
            }
        }
        public bool removenode(TreeDataNode node, TreeDataNode parent)
        {
            TreeDataNode Onode = parent;
            if (parent == null)
                Onode = root;
            /*
            TreeNode it = parent.m_cdls.m_nodelist.Find(
                delegate(TreeNode nd)
                {
                    return nd == node;
                });
            if (it != null)
            {*/
            if (Onode.m_cdls.m_nodelist.Remove(node) == false)
            {
                foreach (TreeDataNode nd in Onode.m_cdls.m_nodelist)
                {
                    if (removenode(node, nd))
                        return true;
                }
             }
             return true;
        }

        public bool movenode(TreeDataNode node, TreeDataNode newparent)
        {
            TreeDataNode Onode = node.parent;
            if (Onode == null)
                return false;

            if (Onode == newparent)
                return true;

            if (null != Onode.m_cdls.m_nodelist.Find(
                        delegate(TreeDataNode nd)
                        {
                            return nd == node;
                        }))
            {
                Onode.m_cdls.m_nodelist.Remove(node);
            }

            newparent.getchildren().m_nodelist.Add(node);
            node.m_parent = newparent;
            return false;
        }

        //private
        //List<TreeNode>	m_nodelist;
    };




} // end namespace 
